package com.ivan.toolkit.network;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;

import lombok.extern.log4j.Log4j2;

@Log4j2
public abstract class TcpListener implements Runnable {
	
	private ServerSocket serverSocket = null;
	
	private Thread thread = null;

	public void start() {
		thread = new Thread(this);
		thread.setName("TcpListener");
		thread.start();
	}

	public void stop() {
		
        try {
            if (serverSocket != null) {
            	serverSocket.close();
            }
        } catch (IOException e) {
        }
		
		try {
			thread.join(3000);
			thread = null;
		} catch (InterruptedException e) {
		}
	}
	
	@Override
	public void run() {
		
		while(serverSocket == null) {
			
			int port = getListenPort();
			
			try {
				
				serverSocket = new ServerSocket(port);
				
				serverSocket.setSoTimeout(2000);
				
				log.info("TcpListener start listen on port " + serverSocket.getLocalPort());
				
			} catch (IOException e) {
			}		
			
			
			while(serverSocket != null) {
				
				try {
					
					Socket socket = serverSocket.accept();
					dispatch(socket);
					
				} catch(SocketTimeoutException e) {
					continue;
				} catch(Exception e) {
					return;
				}
				
			}
			
		}
		
	}
	
	
	protected abstract int getListenPort();
	
	protected abstract void dispatch(Socket socket);

}
